using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;

using SUnit.Core;

namespace SUnit.Gui
{
	public delegate void SelectedTestsChangedEventHandler(object sender, SelectedTestsChangedEventArgs e);
    
	public class TestTree : System.Windows.Forms.UserControl
	{
		#region Instance Variables

		// Our test loader
		//private TestLoader loader;

		private System.Windows.Forms.TabControl tabs;
		private System.Windows.Forms.TabPage testPage;
		//private System.Windows.Forms.TabPage categoryPage;
		private System.Windows.Forms.Panel testPanel;
		private System.Windows.Forms.Panel categoryPanel;
		private System.Windows.Forms.Panel treePanel;
		private System.Windows.Forms.Panel buttonPanel;
		private SUnit.Gui.TestSuiteTreeView tests;
		private System.Windows.Forms.GroupBox groupBox1;
		private System.Windows.Forms.ListBox availableList;
        //private System.Windows.Forms.GroupBox selectedCategories;
        //private System.Windows.Forms.ListBox selectedList;
		private System.Windows.Forms.Panel categoryButtonPanel;
		private System.Windows.Forms.Button addCategory;
		private System.Windows.Forms.Button removeCategory;
		private System.Windows.Forms.Button clearAllButton;
		private System.Windows.Forms.Button checkFailedButton;
		private System.Windows.Forms.MenuItem treeMenu;
		private System.Windows.Forms.MenuItem checkBoxesMenuItem;
		private System.Windows.Forms.MenuItem treeMenuSeparatorItem1;
		private System.Windows.Forms.MenuItem expandMenuItem;
		private System.Windows.Forms.MenuItem collapseMenuItem;
		private System.Windows.Forms.MenuItem treeMenuSeparatorItem2;
		private System.Windows.Forms.MenuItem expandAllMenuItem;
		private System.Windows.Forms.MenuItem collapseAllMenuItem;
		private System.Windows.Forms.MenuItem treeMenuSeparatorItem3;
		private System.Windows.Forms.MenuItem expandFixturesMenuItem;
		private System.Windows.Forms.MenuItem collapseFixturesMenuItem;
		private System.Windows.Forms.MenuItem treeMenuSeparatorItem4;
		private System.Windows.Forms.MenuItem propertiesMenuItem;
        private System.Windows.Forms.CheckBox excludeCheckbox;

        private IContainer components;
		#endregion        

		#region Properties

		public MenuItem TreeMenu 
		{
			get { return treeMenu; }
		}		

		public bool ShowCheckBoxes
		{
			get { return tests.CheckBoxes; }
			set 
			{ 
				tests.CheckBoxes = value;
				buttonPanel.Visible	= value;
				clearAllButton.Visible = value;
				checkFailedButton.Visible = value;
				checkBoxesMenuItem.Checked = value;
			}
		}

		public bool VisualStudioSupport
		{
			get { return tests.VisualStudioSupport; }
			set { tests.VisualStudioSupport = value; }
		}

		public TestSuiteTreeView.DisplayStyle InitialDisplay
		{
			get { return tests.InitialDisplay; }
			set { tests.InitialDisplay = value; }
		}

        public TestSuiteTreeView Tests
        {
            get { return tests; }
        }

		#endregion

		#region Construction and Initialization

		public TestTree()
		{
			// This call is required by the Windows.Forms Form Designer.
			InitializeComponent();
			treeMenu = new MenuItem();
			this.checkBoxesMenuItem = new System.Windows.Forms.MenuItem();
			this.treeMenuSeparatorItem1 = new System.Windows.Forms.MenuItem();
			this.expandMenuItem = new System.Windows.Forms.MenuItem();
			this.collapseMenuItem = new System.Windows.Forms.MenuItem();
			this.treeMenuSeparatorItem2 = new System.Windows.Forms.MenuItem();
			this.expandAllMenuItem = new System.Windows.Forms.MenuItem();
			this.collapseAllMenuItem = new System.Windows.Forms.MenuItem();
			this.treeMenuSeparatorItem3 = new System.Windows.Forms.MenuItem();
			this.expandFixturesMenuItem = new System.Windows.Forms.MenuItem();
			this.collapseFixturesMenuItem = new System.Windows.Forms.MenuItem();
			this.treeMenuSeparatorItem4 = new System.Windows.Forms.MenuItem();
			this.propertiesMenuItem = new System.Windows.Forms.MenuItem();

			// 
			// treeMenu
			// 
			this.treeMenu.MergeType = MenuMerge.Add;
			this.treeMenu.MergeOrder = 1;
			this.treeMenu.MenuItems.AddRange(
				new System.Windows.Forms.MenuItem[] 
				{
					this.checkBoxesMenuItem,
					this.treeMenuSeparatorItem1,
					this.expandMenuItem,
					this.collapseMenuItem,
					this.treeMenuSeparatorItem2,
					this.expandAllMenuItem,
					this.collapseAllMenuItem,
					this.treeMenuSeparatorItem3,
					this.expandFixturesMenuItem,
					this.collapseFixturesMenuItem,
					this.treeMenuSeparatorItem4,
					this.propertiesMenuItem 
				} );
			this.treeMenu.Text = "&Tree";
			this.treeMenu.Visible = false;
			this.treeMenu.Popup += new System.EventHandler(this.treeMenu_Popup);
			// 
			// checkBoxesMenuItem
			// 
			this.checkBoxesMenuItem.Index = 0;
			this.checkBoxesMenuItem.Text = "Show Check&Boxes";
			this.checkBoxesMenuItem.Click += new System.EventHandler(this.checkBoxesMenuItem_Click);
			// 
			// treeMenuSeparatorItem1
			// 
			this.treeMenuSeparatorItem1.Index = 1;
			this.treeMenuSeparatorItem1.Text = "-";
			// 
			// expandMenuItem
			// 
			this.expandMenuItem.Index = 2;
			this.expandMenuItem.Text = "&Expand";
			this.expandMenuItem.Click += new System.EventHandler(this.expandMenuItem_Click);
			// 
			// collapseMenuItem
			// 
			this.collapseMenuItem.Index = 3;
			this.collapseMenuItem.Text = "&Collapse";
			this.collapseMenuItem.Click += new System.EventHandler(this.collapseMenuItem_Click);
			// 
			// treeMenuSeparatorItem2
			// 
			this.treeMenuSeparatorItem2.Index = 4;
			this.treeMenuSeparatorItem2.Text = "-";
			// 
			// expandAllMenuItem
			// 
			this.expandAllMenuItem.Index = 5;
			this.expandAllMenuItem.Text = "Expand All";
			this.expandAllMenuItem.Click += new System.EventHandler(this.expandAllMenuItem_Click);
			// 
			// collapseAllMenuItem
			// 
			this.collapseAllMenuItem.Index = 6;
			this.collapseAllMenuItem.Text = "Collapse All";
			this.collapseAllMenuItem.Click += new System.EventHandler(this.collapseAllMenuItem_Click);
			// 
			// treeMenuSeparatorItem3
			// 
			this.treeMenuSeparatorItem3.Index = 7;
			this.treeMenuSeparatorItem3.Text = "-";
			// 
			// expandFixturesMenuItem
			// 
			this.expandFixturesMenuItem.Index = 8;
			this.expandFixturesMenuItem.Text = "Expand Fixtures";
			this.expandFixturesMenuItem.Click += new System.EventHandler(this.expandFixturesMenuItem_Click);
			// 
			// collapseFixturesMenuItem
			// 
			this.collapseFixturesMenuItem.Index = 9;
			this.collapseFixturesMenuItem.Text = "Collapse Fixtures";
			this.collapseFixturesMenuItem.Click += new System.EventHandler(this.collapseFixturesMenuItem_Click);
			// 
			// treeMenuSeparatorItem4
			// 
			this.treeMenuSeparatorItem4.Index = 10;
			this.treeMenuSeparatorItem4.Text = "-";
			// 
			// propertiesMenuItem
			// 
			this.propertiesMenuItem.Index = 11;
			this.propertiesMenuItem.Text = "&Properties";
			//this.propertiesMenuItem.Click += new System.EventHandler(this.propertiesMenuItem_Click);


			tests.SelectedTestChanged += new SelectedTestChangedHandler(tests_SelectedTestChanged);
			//tests.CheckedTestChanged += new CheckedTestChangedHandler(tests_CheckedTestChanged);

			this.excludeCheckbox.Enabled = false;
		}

        //public void Initialize(TestLoader loader) 
        //{
        //    this.tests.Initialize(loader, loader.Events);
        //    this.loader = loader;
        //    loader.Events.TestLoaded += new NUnit.Util.TestEventHandler(events_TestLoaded);
        //    loader.Events.TestReloaded += new NUnit.Util.TestEventHandler(events_TestReloaded);
        //    loader.Events.TestUnloaded += new NUnit.Util.TestEventHandler(Events_TestUnloaded);
        //}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#endregion

		#region Event Handlers

		private void treeMenu_Popup(object sender, System.EventArgs e)
		{
			TreeNode selectedNode = tests.SelectedNode;
			if ( selectedNode != null && selectedNode.Nodes.Count > 0 )
			{
				bool isExpanded = selectedNode.IsExpanded;
				collapseMenuItem.Enabled = isExpanded;
				expandMenuItem.Enabled = !isExpanded;		
			}
			else
			{
				collapseMenuItem.Enabled = expandMenuItem.Enabled = false;
			}
		}

		private void collapseMenuItem_Click(object sender, System.EventArgs e)
		{
			tests.SelectedNode.Collapse();
		}

		private void expandMenuItem_Click(object sender, System.EventArgs e)
		{
			tests.SelectedNode.Expand();
		}

		private void collapseAllMenuItem_Click(object sender, System.EventArgs e)
		{
			tests.CollapseAll();

			// Compensate for a bug in the underlying control
			if ( tests.Nodes.Count > 0 )
				tests.SelectedNode = tests.Nodes[0];	
		}

		private void expandAllMenuItem_Click(object sender, System.EventArgs e)
		{
			tests.ExpandAll();
		}

		private void collapseFixturesMenuItem_Click(object sender, System.EventArgs e)
		{
			tests.CollapseFixtures();		
		}

		private void expandFixturesMenuItem_Click(object sender, System.EventArgs e)
		{
			tests.ExpandFixtures();		
		}

        private void tests_SelectedTestChanged(TestSuiteTreeNode test)
        {
            if (SelectedTestsChanged != null)
            {
                SelectedTestsChanged(test);
            }
        }

        private void checkBoxesMenuItem_Click(object sender, System.EventArgs e)
        {
            ShowCheckBoxes = !checkBoxesMenuItem.Checked;
        }

        private void tests_RunRequest(object sender, RunRequestEventArgs e)
        {
            if (RunRequest != null)
            {
                RunRequest(sender, e);
            }
        }

		#endregion

		#region Component Designer generated code
		/// <summary> 
		/// Required method for Designer support - do not modify 
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            this.components = new System.ComponentModel.Container();
            this.tabs = new System.Windows.Forms.TabControl();
            this.testPage = new System.Windows.Forms.TabPage();
            this.testPanel = new System.Windows.Forms.Panel();
            this.treePanel = new System.Windows.Forms.Panel();
            this.tests = new SUnit.Gui.TestSuiteTreeView();
            this.buttonPanel = new System.Windows.Forms.Panel();
            this.checkFailedButton = new System.Windows.Forms.Button();
            this.clearAllButton = new System.Windows.Forms.Button();
            this.categoryPanel = new System.Windows.Forms.Panel();
            this.categoryButtonPanel = new System.Windows.Forms.Panel();
            this.removeCategory = new System.Windows.Forms.Button();
            this.addCategory = new System.Windows.Forms.Button();
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.availableList = new System.Windows.Forms.ListBox();
            this.excludeCheckbox = new System.Windows.Forms.CheckBox();
            this.tabs.SuspendLayout();
            this.testPage.SuspendLayout();
            this.testPanel.SuspendLayout();
            this.treePanel.SuspendLayout();
            this.buttonPanel.SuspendLayout();
            this.categoryPanel.SuspendLayout();
            this.categoryButtonPanel.SuspendLayout();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            // 
            // tabs
            // 
            this.tabs.Controls.Add(this.testPage);
            this.tabs.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tabs.Location = new System.Drawing.Point(0, 0);
            this.tabs.Name = "tabs";
            this.tabs.SelectedIndex = 0;
            this.tabs.Size = new System.Drawing.Size(248, 496);
            this.tabs.TabIndex = 0;
            // 
            // testPage
            // 
            this.testPage.Controls.Add(this.testPanel);
            this.testPage.Location = new System.Drawing.Point(4, 22);
            this.testPage.Name = "testPage";
            this.testPage.Size = new System.Drawing.Size(240, 470);
            this.testPage.TabIndex = 0;
            this.testPage.Text = "Tests";
            // 
            // testPanel
            // 
            this.testPanel.Controls.Add(this.treePanel);
            this.testPanel.Controls.Add(this.buttonPanel);
            this.testPanel.Dock = System.Windows.Forms.DockStyle.Fill;
            this.testPanel.Location = new System.Drawing.Point(0, 0);
            this.testPanel.Name = "testPanel";
            this.testPanel.Size = new System.Drawing.Size(240, 470);
            this.testPanel.TabIndex = 0;
            // 
            // treePanel
            // 
            this.treePanel.Controls.Add(this.tests);
            this.treePanel.Dock = System.Windows.Forms.DockStyle.Fill;
            this.treePanel.Location = new System.Drawing.Point(0, 0);
            this.treePanel.Name = "treePanel";
            this.treePanel.Size = new System.Drawing.Size(240, 430);
            this.treePanel.TabIndex = 0;
            // 
            // tests
            // 
            this.tests.AllowDrop = true;
            this.tests.CheckBoxes = true;
            this.tests.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tests.HideSelection = false;
            this.tests.ImageIndex = 0;
            this.tests.Location = new System.Drawing.Point(0, 0);
            this.tests.Name = "tests";
            this.tests.SelectedImageIndex = 0;
            this.tests.Size = new System.Drawing.Size(240, 430);
            this.tests.TabIndex = 0;
            this.tests.RunRequest += new SUnit.Gui.RunRequestEventHandler(this.tests_RunRequest);
            // 
            // buttonPanel
            // 
            this.buttonPanel.Controls.Add(this.checkFailedButton);
            this.buttonPanel.Controls.Add(this.clearAllButton);
            this.buttonPanel.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.buttonPanel.Location = new System.Drawing.Point(0, 430);
            this.buttonPanel.Name = "buttonPanel";
            this.buttonPanel.Size = new System.Drawing.Size(240, 40);
            this.buttonPanel.TabIndex = 1;
            // 
            // checkFailedButton
            // 
            this.checkFailedButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
            this.checkFailedButton.Location = new System.Drawing.Point(128, 8);
            this.checkFailedButton.Name = "checkFailedButton";
            this.checkFailedButton.Size = new System.Drawing.Size(96, 23);
            this.checkFailedButton.TabIndex = 1;
            this.checkFailedButton.Text = "Check Failed";
            // 
            // clearAllButton
            // 
            this.clearAllButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
            this.clearAllButton.Location = new System.Drawing.Point(24, 8);
            this.clearAllButton.Name = "clearAllButton";
            this.clearAllButton.Size = new System.Drawing.Size(96, 23);
            this.clearAllButton.TabIndex = 0;
            this.clearAllButton.Text = "Clear All";
            // 
            // categoryPanel
            // 
            this.categoryPanel.Controls.Add(this.categoryButtonPanel);
            this.categoryPanel.Controls.Add(this.groupBox1);
            this.categoryPanel.Dock = System.Windows.Forms.DockStyle.Fill;
            this.categoryPanel.Location = new System.Drawing.Point(0, 0);
            this.categoryPanel.Name = "categoryPanel";
            this.categoryPanel.Size = new System.Drawing.Size(240, 467);
            this.categoryPanel.TabIndex = 0;
            // 
            // categoryButtonPanel
            // 
            this.categoryButtonPanel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.categoryButtonPanel.Controls.Add(this.removeCategory);
            this.categoryButtonPanel.Controls.Add(this.addCategory);
            this.categoryButtonPanel.Location = new System.Drawing.Point(8, 256);
            this.categoryButtonPanel.Name = "categoryButtonPanel";
            this.categoryButtonPanel.Size = new System.Drawing.Size(224, 40);
            this.categoryButtonPanel.TabIndex = 1;
            // 
            // removeCategory
            // 
            this.removeCategory.Anchor = System.Windows.Forms.AnchorStyles.Top;
            this.removeCategory.Location = new System.Drawing.Point(120, 8);
            this.removeCategory.Name = "removeCategory";
            this.removeCategory.Size = new System.Drawing.Size(75, 23);
            this.removeCategory.TabIndex = 1;
            this.removeCategory.Text = "Remove";
            // 
            // addCategory
            // 
            this.addCategory.Anchor = System.Windows.Forms.AnchorStyles.Top;
            this.addCategory.Location = new System.Drawing.Point(32, 8);
            this.addCategory.Name = "addCategory";
            this.addCategory.Size = new System.Drawing.Size(75, 23);
            this.addCategory.TabIndex = 0;
            this.addCategory.Text = "Add";
            // 
            // groupBox1
            // 
            this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.groupBox1.Controls.Add(this.availableList);
            this.groupBox1.Location = new System.Drawing.Point(8, 16);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(224, 232);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "Available Categories";
            // 
            // availableList
            // 
            this.availableList.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
                        | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.availableList.Location = new System.Drawing.Point(8, 24);
            this.availableList.Name = "availableList";
            this.availableList.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
            this.availableList.Size = new System.Drawing.Size(208, 196);
            this.availableList.TabIndex = 0;
            // 
            // excludeCheckbox
            // 
            this.excludeCheckbox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
                        | System.Windows.Forms.AnchorStyles.Right)));
            this.excludeCheckbox.Location = new System.Drawing.Point(8, 128);
            this.excludeCheckbox.Name = "excludeCheckbox";
            this.excludeCheckbox.Size = new System.Drawing.Size(200, 16);
            this.excludeCheckbox.TabIndex = 1;
            this.excludeCheckbox.Text = "Exclude these categories";
            // 
            // TestTree
            // 
            this.Controls.Add(this.tabs);
            this.Name = "TestTree";
            this.Size = new System.Drawing.Size(248, 496);
            this.tabs.ResumeLayout(false);
            this.testPage.ResumeLayout(false);
            this.testPanel.ResumeLayout(false);
            this.treePanel.ResumeLayout(false);
            this.buttonPanel.ResumeLayout(false);
            this.categoryPanel.ResumeLayout(false);
            this.categoryButtonPanel.ResumeLayout(false);
            this.groupBox1.ResumeLayout(false);
            this.ResumeLayout(false);

		}
		#endregion

		#region Events

		public event SelectedTestChangedHandler SelectedTestsChanged;

        public event RunRequestEventHandler RunRequest;

		#endregion

        #region Public Methods

        public void AddTests(TestInfo test)
        {
            tests.Add(test);  
        }

		public void RunTests()
		{
			tests.RunTests();
        }

        #endregion
    }

    public class SelectedTestsChangedEventArgs : EventArgs
    {
        private string testName;
        private int count;

        public SelectedTestsChangedEventArgs(string testName, int count)
        {
            this.testName = testName;
            this.count = count;
        }

        public string TestName
        {
            get { return testName; }
        }

        public int TestCount
        {
            get { return count; }
        }
    }
}
